package com.hengxin.shiro.matcher;

import java.util.concurrent.atomic.AtomicInteger;

import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.ExcessiveAttemptsException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.CacheManager;

import cn.singno.bob.common.utils.EncryptUtil;

import com.hengxin.bean.ShiroUserm;
import com.hengxin.constant.CacheConstant;
import com.hengxin.shiro.bean.CaptchaUsernamePasswordToken;


/**
 * <p>名称：RetryLimitHashedCredentialsMatcher.java</p>
 * <p>描述：</p>
 * <pre>
 *  密码重试次数限制
 * 散列凭证匹配器  
 * </pre>
 * @author 鲍建明
 * @date 2014-11-9 下午1:03:25
 * @version 1.0.0
 */
public class RetryLimitHashedCredentialsMatcher extends HashedCredentialsMatcher {

	
	/**
	 * 密码限制缓存
	 */
	private Cache<String, AtomicInteger> passwordRetryCache;
	
	/**
	 * 重试的次数
	 */
	private Integer tryCount;
	
	public RetryLimitHashedCredentialsMatcher(){
	}
	

	public RetryLimitHashedCredentialsMatcher(CacheManager cacheManager){
		  passwordRetryCache = cacheManager.getCache(CacheConstant.PASSWORD_RETRY_CACHE);
	}
	
	/**
	 * @param tryCount the tryCount to set
	 */
	public void setTryCount(Integer tryCount) {
		this.tryCount = tryCount;
	}


	/**
	 * 密码匹配器
	 */
	@Override
	public boolean doCredentialsMatch(AuthenticationToken authenticationToken,
			AuthenticationInfo info) {
		CaptchaUsernamePasswordToken  token  = (CaptchaUsernamePasswordToken)authenticationToken;
		String username = token.getUsername();
		AtomicInteger retryCount = passwordRetryCache.get(username);
		
	    if(retryCount == null) {
            passwordRetryCache.put(username, new AtomicInteger(0));
        } else if(retryCount.incrementAndGet() > this.tryCount) {			//超过5次后请过一段时间后，再试
            throw new ExcessiveAttemptsException();			//过多的尝试异常
        }
        boolean matches = this.doMatchPwd(token, info);
      //  boolean matches = super.doCredentialsMatch(token, info);
        if(matches) {
            passwordRetryCache.remove(username);
        }
		return matches;
	}
	

	/**
	 * 自定义密码匹配，也可以使用父类的密码匹配方式
	 * <p>描述：</p>
	 * <pre>
	 *    
	 * </pre>
	 * @param token
	 * @param info
	 * @return
	 */
	public boolean doMatchPwd(AuthenticationToken authenticationToken,
			AuthenticationInfo info) {
		CaptchaUsernamePasswordToken token = (CaptchaUsernamePasswordToken) authenticationToken;
		SimpleAuthenticationInfo in = (SimpleAuthenticationInfo) info;
		ShiroUserm shiroUserm = (ShiroUserm) in.getPrincipals().getPrimaryPrincipal();
		return  EncryptUtil.customMatchPwd(new String(token.getPassword()), shiroUserm.getSalt(), (String) in.getCredentials());
	}
}
